package fido;

import fido.torrentsite.TorrentSite;
import org.apache.log4j.Logger;
import org.mymediadb.api.mmdb.model.Movie;

import javax.security.auth.login.LoginException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: Anders
 * Date: 16.06.11
 * Time: 02:05
 */
public class TuiController extends UserInterfaceWithFido {
    private static final Logger LOG = Logger.getLogger(Main.class);
    private int filesDownloadedThisSession = 0;
    private int wishlistedMoviesLeft = 0;

    public void startUserInterface(String[] args) {
        LOG.info("");
        LOG.info("                |\\");
        LOG.info("        /    /\\/o\\_");
        LOG.info("       (.-.__.(   __o");
        LOG.info("    /\\_(      .----'");
        LOG.info("     .' \\____/");
        LOG.info("    /   /  / \\");
        LOG.info("___:____\\__\\__\\____Wooof woof,  Welcome to Fido");
        LOG.info("Your setting files are at " + FidoCommonUtils.getSettingsDirectory());
        LOG.info("To reinstall run: fido -install");

        handleArguments(args);

        String downloadLocation = FidoCommonUtils.getPropertyValue("fido.directory.torrents");

        TorrentSites torrentSites = TorrentSites.instance();
        torrentSites.select(FidoCommonUtils.getPropertyValue("fido.current.trackers"));
        if (downloadLocation.equals("") || torrentSites.getSelectedTorrentSitesCount() <= 0) {
            LOG.info("Running fido install");
            installFido();
            System.exit(0);
        }

        LOG.info("Looking up your wishlist .....Please wait......");

        torrentSites.makeSureAllSelectedTorrentSitesAreConfiguredTUI();

        //Find movies you have wish listed
        List<Movie> wishListedMovies = null;
        try {
            wishListedMovies = MmdbUtils.getWishlistedMovies();
        } catch (LoginException e) {
            LOG.info("Wrong username/password for mymediadb.org,  please run: fido -install");
            System.exit(-1);
        }
        if (wishListedMovies.size() == 0) {
            LOG.info("Woof. No wish listed movies on mymediadb.org , Going to my dog house");
        } else {
            wishlistedMoviesLeft = wishListedMovies.size();
            LOG.info("Found " + wishlistedMoviesLeft + " on your wishlist. I`ll fetch them one by one!");
            fido.setDownloadLocation(downloadLocation);
            fido.goFetch(wishListedMovies);
        }
    }

    private void handleArguments(String[] args) {
        //### ARGUMENTS
        for (int i = 0; i < args.length; i++) {

            if (args[i].equalsIgnoreCase("-install")) {
                installFido();
                System.exit(0);
            } else if (args[i].equalsIgnoreCase("-torrentsitesInstall")) {
                saveTorrentSites(setupTorrentSites());
                System.exit(0);
            } else if (args[i].equalsIgnoreCase("-help") || args[i].equalsIgnoreCase("-h")) {
                LOG.info("");
                LOG.info("Help -HELP");
                LOG.info("Your setting files are located at: " + FidoCommonUtils.getSettingsDirectory());
                LOG.info("By using your setting files, you don't need extra arguments!");
                LOG.info("");
                LOG.info("However available arguments are as follows:");
                LOG.info("-install starts the program in install mode.");
                LOG.info("-torrentsitesInstall starts the program in install mode for torrent sites");
                LOG.info("-username sets your mymediadb.org username");
                LOG.info("-password sets you mymediadb.org password");
                LOG.info("-torrentsite  sets your torrent site");
                LOG.info("-list  Lists available torrent sites:");
                LOG.info("-dir  sets you save directory");
                LOG.info("-property <propertykey> <propertyvalue>"); //-property  fido.TorrentLeech.cookies "tluid=45345; tlpass=sdf34w9f34fm"

                System.exit(0);

            } else if (args[i].equalsIgnoreCase("-username")) {
                FidoCommonUtils.setProperty("fido.mmdb.username", args[++i]);
                LOG.info("Username is now set to:" + FidoCommonUtils.getPropertyValue("fido.mmdb.username"));
            } else if (args[i].equalsIgnoreCase("-password")) {
                FidoCommonUtils.setProperty(FidoCommonUtils.fidoMmdbPassword, args[++i]);
                LOG.info("Password is now set to:" + FidoCommonUtils.getPropertyValue(FidoCommonUtils.fidoMmdbPassword));
            } else if (args[i].equalsIgnoreCase("-torrentsite")) {
                List<String> trackers = new ArrayList<String>();
                trackers.add(args[++i]);
                FidoCommonUtils.setProperty("fido.current.trackers", trackers.toString());
                LOG.info("Torrentsite is now set to:" + FidoCommonUtils.getPropertyValue("fido.current.trackers"));
            } else if (args[i].equalsIgnoreCase("-dir")) {
                FidoCommonUtils.setProperty("fido.directory.torrents", args[++i]);
                LOG.info("Directory is now set to:" + FidoCommonUtils.getPropertyValue("fido.directory.torrents"));
            } else if (args[i].equalsIgnoreCase("-property")) {
                FidoCommonUtils.setProperty(args[++i], args[++i]);
                LOG.info("Property for:" + args[i - 1] + "=" + FidoCommonUtils.getPropertyValue(args[i - 1]));
            } else if (args[i].equalsIgnoreCase("-list")) {
                LOG.info("Available torrent sites");
                for (Class c : FidoCommonUtils.getAllTorrentSiteClasses()) {
                    LOG.info(c.getCanonicalName());
                }
                System.exit(0);
            }

        }


    }

    private void installFido() {

        //Fido installer
        LOG.info("");
        LOG.info("This fido install script will guide you through the initial configuration of Fido.\n" +
                "First off, you need to type your MyMediaDB.org username and password, \n" +
                "if you don't have an account. Please register at MyMediaDB.org. \n" +
                "Press Enter to continue, or ctrl-c to exitFido");
        FidoCommonUtils.readKeyboardInput();
        String mmdbUsername = "";
        String mmdbPassword = "";
        try {
            do {
                LOG.info("Input you MyMediaDB.org username:");
                mmdbUsername = FidoCommonUtils.readKeyboardInput();
                LOG.info("Input you MyMediaDB.org password:");
                mmdbPassword = FidoCommonUtils.readKeyboardInput();
            } while (!FidoCommonUtils.checkUsernameAndPassword(mmdbUsername, mmdbPassword));
            LOG.info("Connection to MyMediaDB.org established");
            LOG.info("");
        } catch (Exception e) {
            LOG.info("Could not log in to mymediadb: Exception " + e.getMessage());
            LOG.info("Continue setup (y/n)?");
            String answer;
            answer = FidoCommonUtils.readKeyboardInput();
            if ((answer.equalsIgnoreCase("N")) || (answer.equalsIgnoreCase("NO"))) {
                System.exit(1);
            }

        }

        //Choosing store location for torrent files
        String torrentStoreLocation;
        do {
            LOG.info("Input the folder you want to save your torrent files");
            torrentStoreLocation = FidoCommonUtils.readKeyboardInput();
            // format the path of the location
            // torrentStoreLocation
            //Test the location
            // testIfFolderIsValid(torrentStoreLocation);
        } while (false); //TODO need to check this folder properly

        //setup torrentSites until a valid site is added.

        String trackers = setupTorrentSites();

        //Save settings file
        FidoCommonUtils.saveGeneralSettings(mmdbUsername, mmdbPassword, torrentStoreLocation, null, trackers);
        LOG.info("Please restart! to start using Fido");
        LOG.info("Press Enter to exitFido.");
        FidoCommonUtils.readKeyboardInput();
    }

    private void saveTorrentSites(String torrentSites) {
        FidoCommonUtils.saveGeneralSettings(null, null, null, null, torrentSites);
    }

    //Choosing Torrentsite
    private String setupTorrentSites() {
        TorrentSites torrentSites = TorrentSites.instance();
        torrentSites.select(FidoCommonUtils.getSelectedTorrentSitesAsStringList());
        List<TorrentSite> torrentSiteList = torrentSites.getAllTorrentSites();
        LOG.info("-----------------------------------");
//        List<String> trackers = FidoCommonUtils.getSelectedTorrentSitesAsStringList();
        do {
/*            List<String> torrentSites = new ArrayList<String>();
            for (Class c : FidoCommonUtils.getAllTorrentSiteClasses()) {
                torrentSites.add(c.getSimpleName());
            }
*/
            int arrayIndex = Integer.MIN_VALUE;
            do {
                LOG.info("Please choose your torrent trackers:");
                LOG.info(" 0. Finished selecting trackers");
                for (int i = 0; i < torrentSiteList.size(); i++) {
                    TorrentSite torrentSite = torrentSiteList.get(i);
                    String selectedString = "";
                    if (torrentSites.isSelected(torrentSite)) {
                        selectedString = " (selected)";
                    }
                    LOG.info(" " + (i + 1) + ". " + torrentSite.getTorrentSiteAlias() + selectedString);
                }
                boolean correctInputNumber;
                do {
                    LOG.info("Choose a number from the list(0 to " + torrentSiteList.size() + "): ");
                    String chosenTorrentSite = FidoCommonUtils.readKeyboardInput();
                    try {
                        arrayIndex = Integer.parseInt(chosenTorrentSite);
                        correctInputNumber = !(arrayIndex < 0 || arrayIndex > torrentSiteList.size());
                    } catch (NumberFormatException e) {
                        correctInputNumber = false;
                    }
                } while (!correctInputNumber);
                if (arrayIndex != 0) {
                    TorrentSite torrentSite = torrentSiteList.get(arrayIndex - 1);
                    if (torrentSites.isSelected(torrentSite)) {
                        torrentSites.deselect(torrentSite);
                        LOG.info("Removed: " + torrentSite);
                    } else {
                        torrentSites.select(torrentSite);
                        torrentSites.makeSureAllSelectedTorrentSitesAreConfiguredTUI();
                        LOG.info("Added: " + torrentSite);
                    }
                }

            } while (arrayIndex != 0);
            if (torrentSites.getSelectedTorrentSitesCount() == 0) {
                LOG.info("No trackers were selected. Please try again.");
            } else {
                LOG.info("The following torrent sites was selected: " + torrentSites.getAllSelectedSitesAsString());
            }
        } while (torrentSites.getSelectedTorrentSitesCount() <= 0);
        return torrentSites.getAllSelectedSitesAsString();
    }

    @Override
    public void showMessage(String message) {
        LOG.info(message);
    }

    @Override
    public void fidoStartedFetching() {
        showMessage("Fido started looking for movies in your wishlist");
    }


    @Override
    public void fidoFinishedSearching() {
        showMessage("\nFido finished searching for movies in your wishlist.");
        showMessage(filesDownloadedThisSession + " files was downloaded.");
    }

    @Override
    public void fidoIsAttemptingToFetch(Movie movie) {
        showMessage(wishlistedMoviesLeft-- + " movie(s) left. Go fetch: " + movie.getName());
    }

    @Override
    public void fidoFetchedMovie(Movie movie, Torrent torrent) {
        showMessage("Woof! Found torrent for '" + movie.getName() + "' on '" + torrent.getTorrentSiteName() + "'. Save file.");
        filesDownloadedThisSession++;
    }

    @Override
    public void fidoCouldNotFetch(Movie movie, String torrentSiteNames) {
        showMessage("Didn't find torrent for '" + movie.getName() + "' in '" + torrentSiteNames + "'.");
    }


}
